
package lxycx.clazz;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * 从远程加载Class
 * @author XingChao
 * @version 2019年2月1日
 */
public class NetworkClassLoader extends ClassLoader {
	private String rooturl;
	private String encode;
	
	public NetworkClassLoader(String rooturl) {
		this.rooturl = rooturl;
	}
	public NetworkClassLoader(String rooturl,String encode) {
		this.rooturl = rooturl;
		this.encode = encode;
	}
	
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		byte[] classdata = null;
		if("DE100".equals(encode)){
			classdata = getClassDataDE100(name);
		}else {
			classdata = getClassData(name);
		}
		
		if(classdata==null){
			throw new ClassNotFoundException("远程加载:"+name+"失败");
		}
		return defineClass(name, classdata, 0, classdata.length);
	}

	
	//加载class数据
	private byte[] getClassData(String name) {
		InputStream is = null;  
        try {  
            String path = classNameToPath(name);  
            URL url = new URL(path);  
            byte[] buff = new byte[4096];
            int len = -1;  
            is = url.openStream();  
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
            while((len = is.read(buff)) != -1) {  
                baos.write(buff,0,len);  
            }  
            return baos.toByteArray();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (is != null) {  
               try {  
                  is.close();  
               } catch(IOException e) {  
                  e.printStackTrace();  
               }  
            }  
        }  
        return null; 
	}
	

	private byte[] getClassDataDE100(String name) {
		InputStream is = null;  
        try {  
            String path = classNameToPath(name);  
            URL url = new URL(path);  
            byte[] buff = new byte[100];
            int len = -1;  
            is = url.openStream();  
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
            while((len = is.read(buff)) != -1) {  
                baos.write(buff,0,len-1);
            }  
            return baos.toByteArray();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (is != null) {  
               try {  
                  is.close();  
               } catch(IOException e) {  
                  e.printStackTrace();  
               }  
            }  
        }  
        return null; 
	}
	
	private String classNameToPath(String name) {  
        return rooturl + "/" + name.replace(".", "/") + ".class";  
    }  
	
}

